﻿//--------------------------------------------------------------------------
// 
//  Copyright (c) Chili Software.  All rights reserved. 
// 
//  File: PersistentAttribute.cs
//
//  Description: Marks a class as persistent object.
// 
//--------------------------------------------------------------------------

using System;
using System.Reflection;

namespace Chili.Opf3
{
	/// <summary>Marks a class as a persistent object.</summary>
	/// <remarks>
	/// This attribute is used to mark a class as persistent. As constructor argument has
	/// to be specified the name of the entity in the storage. The attribute allows also to
	/// specify the size of the pre-cached persistent object pool by modifying the
	/// <see cref="PersistentAttribute.PoolSize">PoolSize</see> property (default is 0, which
	/// means no pool is created). The pool is a cache that contains empty objects that are 
	/// used during heavy loads.
	/// </remarks>
	/// <example>
	///     The following example shows a User persistent associated with the "USER" entity in
	///     the storage. The pool size set to 100 objects to gain speed on heavy
	///     loads. The <see cref="FieldAttribute">FieldAttribute</see> is used to connect a
	///     property with a field of the entity.
	///     <code lang="CS">
	/// [Persistent("USER", PoolSize = 100)]
	/// public class User
	/// {
	///     private string _name = null;
	///     
	///     [Field("NAME")]
	///     public string Name
	///     {
	///         get { return _name; }
	///         set { _name = value; }
	///     }
	///     
	///     // ... Other properties and fields.
	/// }
	///     </code>
	/// </example>
	[Serializable]
	[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
	public sealed class PersistentAttribute : Attribute
	{
		private string _entity;
		private int _poolSize;
		private PersistentRights _rights = PersistentRights.All;

		/// <summary>
		/// Creates a new instance of the <see cref="PersistentAttribute">PersistentAttribute Class</see>.
		/// </summary>
		public PersistentAttribute()
		{
		}

		/// <summary>
		/// Creates a new instance of the <see cref="PersistentAttribute">PersistentAttribute Class</see>.
		/// </summary>
		/// <param name="entity">Enitity of the storage that is associated with the persistent.</param>
		/// <exception cref="System.ArgumentNullException">Entity is null.</exception>
		public PersistentAttribute(string entity)
		{
			// Throw an exception if the entity hasn't been set.
			if (entity == null)
				throw new ArgumentNullException("entity");
			_entity = entity;
		}

		/// <summary>
		/// Gets or sets the entity of the storage that is associated with the persistent
		/// object.
		/// </summary>
		/// <value>A string that represents the entity associated with the object.</value>
		public string Entity
		{
			get { return _entity; }
			set 
			{
				if (value == null)
					throw new ArgumentNullException("value");

				_entity = value; 
			}
		}

		/// <summary>
		/// 	<para>Specifies the size of the pool (default is 0) that contains pre-cached
		///     instances of the class marked with this attribute.</para>
		/// </summary>
		/// <value>The size of the pool for the persistent object marked with this attribute.</value>
		/// <remarks>
		/// 	<para>This property is usually set if the program loads a lot objects of the given
		///     type in a repeated manner. It allows to speed up loading of large lists.</para>
		/// </remarks>
		public int PoolSize
		{
			get { return _poolSize; }
			set { _poolSize = value; }
		}

		/// <summary>
		/// Specifies the rights of the persistent object.
		/// </summary>
		/// <remarks>
		/// <para>
		/// Specifies the <see cref="PersistentRights">rights</see> of the persistent object. Some persistent
		/// may only be allowed to be loaded and not saved (aka. read-only persistent objects). This property is 
		/// used to grant those rights.
		/// </para>
		/// <para>
		/// By default the persistent object has all rights: see <see cref="PersistentRights.All">PersistentRights.All</see>.
		/// </para>
		/// </remarks>
		/// <value>The rights of the persistent object.</value>
		public PersistentRights Rights
		{
			get { return _rights; }
			set { _rights = value; }
		}
	}
}
